<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='global-property-S-'>/**
</span> * @fileOverview 数据缓冲对象
 * @author dxq613@gmail.com
 * @ignore
 */

  
  var $ = require(&#39;jquery&#39;),
    Proxy = require(&#39;./proxy&#39;),
    AbstractStore = require(&#39;./abstractstore&#39;),
    Sortable = require(&#39;./sortable&#39;);

  //移除数据
  function removeAt(index,array){
    if(index &lt; 0){
      return;
    }
    var records = array,
      record = records[index];
    records.splice(index,1);
    return record;
  }

  function removeFrom(record,array){
    var index = BUI.Array.indexOf(record,array);   
    if(index &gt;= 0){
      removeAt(index,array);
    }
  }

  function contains(record,array){
    return BUI.Array.indexOf(record,array) !== -1;
  }
<span id='BUI-Data-Store'>  /**
</span>   * 用于加载数据，缓冲数据的类
   * &lt;p&gt;
   * &lt;img src=&quot;../assets/img/class-data.jpg&quot;/&gt;
   * &lt;/p&gt;
   * ** 缓存静态数据 ** 
   * &lt;pre&gt;&lt;code&gt;
   *  var store = new Store({
   *    data : [{},{}]
   *  });
   * &lt;/code&gt;&lt;/pre&gt;
   * ** 异步加载数据 **
   * &lt;pre&gt;&lt;code&gt;
   *  var store = new Store({
   *    url : &#39;data.json&#39;,
   *    autoLoad : true,
   *    params : {id : &#39;123&#39;},
   *    sortInfo : {
   *      field : &#39;id&#39;,
   *      direction : &#39;ASC&#39; //ASC,DESC
   *    }
   *  });
   * &lt;/code&gt;&lt;/pre&gt;
   * 
   * @class BUI.Data.Store
   * @extends BUI.Data.AbstractStore
   * @mixins BUI.Data.Sortable
   */
  var store = function(config){
    store.superclass.constructor.call(this,config);
    //this._init();
  };

  store.ATTRS = 
  {
<span id='BUI-Data-Store-cfg-autoSync'>    /**
</span>     * 保存数据时，是否自动更新数据源的数据，常用于添加、删除、更改数据后重新加载数据。
     * @cfg {Boolean} autoSync
     */
    autoSync : {
      value : false
    },
<span id='global-cfg-currentPage'>    /**
</span>     * 当前页码
     * @cfg {Number} [currentPage=0]
     * @ignore
     */
<span id='global-property-currentPage'>    /**
</span>     * 当前页码
     * @type {Number}
     * @ignore
     * @readOnly
     */
    currentPage:{
      value : 0
    },
    
<span id='BUI-Data-Store-property-deletedRecords'>    /**
</span>     * 删除掉的纪录
     * @readOnly
     * @private
     * @type {Array}
     */
    deletedRecords : {
      shared : false,
      value:[]
    },
    

<span id='BUI-Data-Store-property-matchFunction'>    /**
</span>     * 对比2个对象是否相当，在去重、更新、删除，查找数据时使用此函数
     * @default  
     * function(obj1,obj2){
     *   return obj1 == obj2;
     * }
     * @type {Object}
     * @example
     * function(obj1 ,obj2){
     *   //如果id相等，就认为2个数据相等，可以在添加对象时去重
     *   //更新对象时，仅提供改变的字段
     *   return obj1.id == obj2.id;
     * }
     * 
     */
    matchFunction : {
      value : function(obj1,obj2){
        return obj1 == obj2;
      }
    },
<span id='BUI-Data-Store-property-modifiedRecords'>    /**
</span>     * 更改的纪录集合
     * @type {Array}
     * @private
     * @readOnly
     */
    modifiedRecords : {
      shared : false,
      value:[]
    },
<span id='BUI-Data-Store-property-newRecords'>    /**
</span>     * 新添加的纪录集合，只读
     * @type {Array}
     * @private
     * @readOnly
     */
    newRecords : {
      shared : false,
      value : []
    },
<span id='BUI-Data-Store-cfg-remoteSort'>    /**
</span>     * 是否远程排序，默认状态下内存排序
     *   - 由于当前Store存储的不一定是数据源的全集，所以此配置项需要重新读取数据
     *   - 在分页状态下，进行远程排序，会进行全集数据的排序，并返回首页的数据
     *   - remoteSort为 false的情况下，仅对当前页的数据进行排序
     * @cfg {Boolean} [remoteSort=false]
     */
    remoteSort : {
      value : false
    },
<span id='BUI-Data-Store-property-resultMap'>    /**
</span>     * 缓存的数据，包含以下几个字段
     * &lt;ol&gt;
     * &lt;li&gt;rows: 数据集合&lt;/li&gt;
     * &lt;li&gt;results: 总的数据条数&lt;/li&gt;
     * &lt;/ol&gt;
     * @type {Object}
     * @private
     * @readOnly
     */
    resultMap : {
      shared : false,
      value : {}
    },
<span id='BUI-Data-Store-cfg-root'>    /**
</span>     * 加载数据时，返回数据的根目录
     * @cfg {String} [root=&#39;rows&#39;]
     * &lt;pre&gt;&lt;code&gt;
     *    //默认返回数据类型：
     *    &#39;{&quot;rows&quot;:[{&quot;name&quot;:&quot;abc&quot;},{&quot;name&quot;:&quot;bcd&quot;}],&quot;results&quot;:100}&#39;
     *   //可以修改接收的后台参数的含义
     *   var store = new Store({
     *     url : &#39;data.json&#39;,
     *     errorProperty : &#39;errorMsg&#39;, //存放错误信息的字段(error)
     *     hasErrorProperty : &#39;isError&#39;, //是否错误的字段（hasError)
     *     root : &#39;data&#39;,               //存放数据的字段名(rows)
     *     totalProperty : &#39;total&#39;     //存放记录总数的字段名(results)
     *   });
     * &lt;/code&gt;&lt;/pre&gt;
     *   
     */
    root: { value : &#39;rows&#39;}, 

<span id='BUI-Data-Store-property-rowCount'>    /**
</span>     * 当前Store缓存的数据条数
     * @type {Number}
     * @private
     * @readOnly
     */
    rowCount :{
      value : 0
    },
<span id='BUI-Data-Store-cfg-totalProperty'>    /**
</span>     * 加载数据时，返回记录的总数的字段，用于分页
     * @cfg {String} [totalProperty=&#39;results&#39;]
     *&lt;pre&gt;&lt;code&gt;
     *    //默认返回数据类型：
     *    &#39;{&quot;rows&quot;:[{&quot;name&quot;:&quot;abc&quot;},{&quot;name&quot;:&quot;bcd&quot;}],&quot;results&quot;:100}&#39;
     *   //可以修改接收的后台参数的含义
     *   var store = new Store({
     *     url : &#39;data.json&#39;,
     *     errorProperty : &#39;errorMsg&#39;, //存放错误信息的字段(error)
     *     hasErrorProperty : &#39;isError&#39;, //是否错误的字段（hasError)
     *     root : &#39;data&#39;,               //存放数据的字段名(rows)
     *     totalProperty : &#39;total&#39;     //存放记录总数的字段名(results)
     *   });
     * &lt;/code&gt;&lt;/pre&gt;
     */
    totalProperty: {value :&#39;results&#39;}, 

<span id='BUI-Data-Store-property-start'>    /**
</span>     * 加载数据的起始位置
     * &lt;pre&gt;&lt;code&gt;
     *  //初始化时，可以在params中配置
     *  var store = new Store({
     *    url : &#39;data.json&#39;,
     *    params : {
     *      start : 100
     *    }
     *  });
     * &lt;/code&gt;&lt;/pre&gt;
     * @type {Object}
     */
    start:{
      value : 0
    },
<span id='BUI-Data-Store-cfg-pageSize'>    /**
</span>     * 每页多少条记录,默认为null,此时不分页，当指定了此值时分页
     * &lt;pre&gt;&lt;code&gt;
     *  //当请求的数据分页时
     *  var store = new Store({
     *    url : &#39;data.json&#39;,
     *    pageSize : 30
     *  });
     * &lt;/code&gt;&lt;/pre&gt;
     * @cfg {Number} pageSize
     */
    pageSize : {

    }
  };
  BUI.extend(store,AbstractStore);

  BUI.mixin(store,[Sortable]);

  BUI.augment(store,
  {
<span id='BUI-Data-Store-method-add'>    /**
</span>    * 添加记录,默认添加在后面
    * &lt;pre&gt;&lt;code&gt;
    *  //添加记录
    *  store.add({id : &#39;2&#39;,text: &#39;new data&#39;});
    *  //是否去重，重复数据不能添加
    *  store.add(obj,true); //不能添加重复数据，此时用obj1 === obj2判断
    *  //使用匹配函去重
    *  store.add(obj,true,function(obj1,obj2){
    *    return obj1.id == obj2.id;
    *  });
    *  
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Array|Object} data 添加的数据，可以是数组，可以是单条记录
    * @param {Boolean} [noRepeat = false] 是否去重,可以为空，默认： false 
    * @param {Function} [match] 匹配函数，可以为空，
    * @default 配置项中 matchFunction 属性传入的函数，默认是：&lt;br&gt;
    *  function(obj1,obj2){
    *    return obj1 == obj2;
    *  }
    * 
    */
    add :function(data,noRepeat,match){
      var _self = this,
        count = _self.getCount();
      _self.addAt(data,count,noRepeat,match)
    },
<span id='BUI-Data-Store-method-addAt'>    /**
</span>    * 添加记录,指定索引值
    * &lt;pre&gt;&lt;code&gt;
    *  //使用方式跟类似于add,增加了index参数
    *  store.add(obj,0);//添加在最前面
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Array|Object} data 添加的数据，可以是数组，可以是单条记录
    * @param {Number} index 开始添加数据的位置
    * @param {Boolean} [noRepeat = false] 是否去重,可以为空，默认： false 
    * @param {Function} [match] 匹配函数，可以为空，
     */
    addAt : function(data,index,noRepeat,match){
      var _self = this;

      match = match || _self._getDefaultMatch();
      if(!BUI.isArray(data)){
        data = [data];
      }

      $.each(data,function(pos,element){
        if(!noRepeat || !_self.contains(element,match)){
          _self._addRecord(element,pos + index);

          _self.get(&#39;newRecords&#39;).push(element);

          removeFrom(element,_self.get(&#39;deletedRecords&#39;));
          removeFrom(element,_self.get(&#39;modifiedRecords&#39;));
        }
      });
    },
<span id='BUI-Data-Store-method-contains'>    /**
</span>    * 验证是否存在指定记录
    * &lt;pre&gt;&lt;code&gt;
    *  store.contains(obj); //是否包含指定的记录
    *
    *  store.contains(obj,function(obj1,obj2){ //使用匹配函数
    *    return obj1.id == obj2.id;
    *  });
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Object} record 指定的记录
    * @param {Function} [match = function(obj1,obj2){return obj1 == obj2}] 默认为比较2个对象是否相同
    * @return {Boolean}
    */
    contains :function(record,match){
      return this.findIndexBy(record,match)!==-1;
    },
<span id='BUI-Data-Store-method-find'>    /**
</span>    * 查找记录，仅返回第一条
    * &lt;pre&gt;&lt;code&gt;
    *  var record = store.find(&#39;id&#39;,&#39;123&#39;);
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {String} field 字段名
    * @param {String} value 字段值
    * @return {Object|null}
    */
    find : function(field,value){
      var _self = this,
        result = null,
        records = _self.getResult();
      $.each(records,function(index,record){
        if(record[field] === value){
          result = record;
          return false;
        }
      });
      return result;
    },
<span id='BUI-Data-Store-method-findAll'>    /**
</span>    * 查找记录，返回所有符合查询条件的记录
    * &lt;pre&gt;&lt;code&gt;
    *   var records = store.findAll(&#39;type&#39;,&#39;0&#39;);
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {String} field 字段名
    * @param {String} value 字段值
    * @return {Array}
    */
    findAll : function(field,value){
      var _self = this,
        result = [],
        records = _self.getResult();
      $.each(records,function(index,record){
        if(record[field] === value){
          result.push(record);
        }
      });
      return result;
    },
<span id='BUI-Data-Store-method-findByIndex'>    /**
</span>    * 根据索引查找记录
    * &lt;pre&gt;&lt;code&gt;
    *  var record = store.findByIndex(1);
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Number} index 索引
    * @return {Object} 查找的记录
    */
    findByIndex : function(index){
      return this.getResult()[index];
    },
<span id='BUI-Data-Store-method-findIndexBy'>    /**
</span>    * 查找数据所在的索引位置,若不存在返回-1
    * &lt;pre&gt;&lt;code&gt;
    *  var index = store.findIndexBy(obj);
    *
    *  var index = store.findIndexBy(obj,function(obj1,obj2){
    *    return obj1.id == obj2.id;
    *  });
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Object} target 指定的记录
    * @param {Function} [match = matchFunction] @see {BUI.Data.Store#matchFunction}默认为比较2个对象是否相同
    * @return {Number}
    */
    findIndexBy :function(target,match){
      var _self = this,
        position = -1,
        records = _self.getResult();
      match = match || _self._getDefaultMatch();
      if(target === null || target === undefined){
        return -1;
      }
      $.each(records,function(index,record){
        if(match(target,record)){
          position = index;
          return false;
        }
      });
      return position;
    },
<span id='BUI-Data-Store-method-findNextRecord'>    /**
</span>    * 获取下一条记录
    * &lt;pre&gt;&lt;code&gt;
    *  var record = store.findNextRecord(obj);
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Object} record 当前记录
    * @return {Object} 下一条记录
    */
    findNextRecord : function(record){
      var _self = this,
        index = _self.findIndexBy(record);
      if(index &gt;= 0){
        return _self.findByIndex(index + 1);
      }
      return;
    },

<span id='BUI-Data-Store-method-getCount'>    /**
</span>     * 获取缓存的记录数
     * &lt;pre&gt;&lt;code&gt;
     *  var count = store.getCount(); //缓存的数据数量
     *
     *  var totalCount = store.getTotalCount(); //数据的总数，如果有分页时，totalCount != count
     * &lt;/code&gt;&lt;/pre&gt;
     * @return {Number} 记录数
     */
    getCount : function(){
      return this.getResult().length;
    },
<span id='BUI-Data-Store-method-getTotalCount'>    /**
</span>     * 获取数据源的数据总数，分页时，当前仅缓存当前页数据
     * &lt;pre&gt;&lt;code&gt;
     *  var count = store.getCount(); //缓存的数据数量
     *
     *  var totalCount = store.getTotalCount(); //数据的总数，如果有分页时，totalCount != count
     * &lt;/code&gt;&lt;/pre&gt;
     * @return {Number} 记录的总数
     */
    getTotalCount : function(){
      var _self = this,
        resultMap = _self.get(&#39;resultMap&#39;),
        total = _self.get(&#39;totalProperty&#39;),
        totalVal = BUI.getValue(resultMap,total); 
      return parseInt(totalVal,10) || 0;
    },
<span id='BUI-Data-Store-method-getResult'>    /**
</span>     * 获取当前缓存的纪录
     * &lt;pre&gt;&lt;code&gt;
     *   var records = store.getResult();
     * &lt;/code&gt;&lt;/pre&gt;
     * @return {Array} 纪录集合
     */
    getResult : function(){
      var _self = this,
        resultMap = _self.get(&#39;resultMap&#39;),
        root = _self.get(&#39;root&#39;);
      return BUI.getValue(resultMap,root);
    },
<span id='BUI-Data-Store-method-hasData'>    /**
</span>     * 是否包含数据
     * @return {Boolean} 
     */
    hasData : function(){
      return this.getCount() !== 0;
    },
<span id='BUI-Data-Store-method-setResult'>    /**
</span>     * 设置数据源,非异步加载时，设置缓存的数据
     * &lt;pre&gt;&lt;code&gt;
     *   store.setResult([]); //清空数据
     *
     *   var data = [{},{}];
     *   store.setResult(data); //重设数据
     * &lt;/code&gt;&lt;/pre&gt;
     */
    setResult : function(data){
      var _self = this,
        proxy = _self.get(&#39;proxy&#39;);
      if(proxy instanceof Proxy.Memery){
        _self.set(&#39;data&#39;,data);
        _self.load({start:0});
      }else{
        _self._setResult(data);
        //如果有filter则进行过滤
        if(_self.get(&#39;filter&#39;)){
          _self.filter();
        }
      }
    },

<span id='BUI-Data-Store-method-remove'>    /**
</span>    * 删除一条或多条记录触发 remove 事件.
    * &lt;pre&gt;&lt;code&gt;
    *  store.remove(obj);  //删除一条记录
    *
    *  store.remove([obj1,obj2...]); //删除多个条记录
    *
    *  store.remvoe(obj,funciton(obj1,obj2){ //使用匹配函数
    *    return obj1.id == obj2.id;
    *  });
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Array|Object} data 添加的数据，可以是数组，可以是单条记录
    * @param {Function} [match = function(obj1,obj2){return obj1 == obj2}] 匹配函数，可以为空
    */
    remove :function(data,match){
      var _self =this,
        delData=[];
      match = match || _self._getDefaultMatch();
      if(!BUI.isArray(data)){
        data = [data];
      }
      $.each(data,function(index,element){
        var index = _self.findIndexBy(element,match),
            record = removeAt(index,_self.getResult());
        //添加到已删除队列中,如果是新添加的数据，不计入删除的数据集合中
        if(!contains(record,_self.get(&#39;newRecords&#39;)) &amp;&amp; !contains(record,_self.get(&#39;deletedRecords&#39;))){
          _self.get(&#39;deletedRecords&#39;).push(record);
        }
        removeFrom(record,_self.get(&#39;newRecords&#39;));
        removeFrom(record,_self.get(&#39;modifiedRecords&#39;));
        _self.fire(&#39;remove&#39;,{record:record});
      }); 
    },
<span id='BUI-Data-Store-method-save'>    /**
</span>     * 保存数据，有几种类型：
     * 
     *  - add 保存添加的记录,
     *  - remove 保存删除,
     *  - update 保存更新,
     *  - all 保存store从上次加载到目前更改的记录
     *
     * 
     * @param {String} type 保存的类型
     * @param {Object} saveData 数据
     * @param {Function} callback
     */
    save : function(type,saveData,callback){
      var _self = this,
        proxy = _self.get(&#39;proxy&#39;);

      if(BUI.isFunction(type)){ //只有回调函数
        callback = type;
        type = undefined;
      }
      if(BUI.isObject(type)){ //未指定类型
        callback = saveData;
        saveData = type;
        type = undefined;
      }
      if(!type){
        type = _self._getSaveType(saveData);
      }
      if(type == &#39;all&#39; &amp;&amp; !saveData){//如果保存全部，同时未提供保存的数据，自动获取
        saveData = _self._getDirtyData();
      }

      _self.fire(&#39;beforesave&#39;,{type : type,saveData : saveData});

      proxy.save(type,saveData,function(data){
        _self.onSave(type,saveData,data);
        if(callback){
          callback(data,saveData);
        }
      },_self);

    },
    //根据保存的数据获取保存的类型
    _getSaveType :function(saveData){
      var _self = this;
      if(!saveData){
        return &#39;all&#39;;
      }

      if(BUI.Array.contains(saveData,_self.get(&#39;newRecords&#39;))){
        return &#39;add&#39;;
      }

      if(BUI.Array.contains(saveData,_self.get(&#39;modifiedRecords&#39;))){
        return &#39;update&#39;;
      }

      if(BUI.Array.contains(saveData,_self.get(&#39;deletedRecords&#39;))){
        return &#39;remove&#39;;
      }
      return &#39;custom&#39;;
    },
    //获取未保存的数据
    _getDirtyData : function(){
      var _self = this,
        proxy = _self.get(&#39;proxy&#39;);
      if(proxy.get(&#39;url&#39;)){
        return {
          add : BUI.JSON.stringify(_self.get(&#39;newRecords&#39;)),
          update : BUI.JSON.stringify(_self.get(&#39;modifiedRecords&#39;)),
          remove : BUI.JSON.stringify(_self.get(&#39;deletedRecords&#39;))
        };
      }else{
        return {
          add : _self.get(&#39;newRecords&#39;),
          update : _self.get(&#39;modifiedRecords&#39;),
          remove : _self.get(&#39;deletedRecords&#39;)
        };
      }
      
    },
<span id='BUI-Data-Store-method-onSave'>    /**
</span>     * 保存完成后
     * @private
     */
    onSave : function(type,saveData,data){
      var _self = this,
         hasErrorField = _self.get(&#39;hasErrorProperty&#39;);

      if (BUI.getValue(data,hasErrorField) || data.exception){ //如果失败
        _self.onException(data);
        return;
      }
      _self._clearDirty(type,saveData);

      _self.fire(&#39;saved&#39;,{type : type,saveData : saveData,data : data});
      if(_self.get(&#39;autoSync&#39;)){
        _self.load();
      }
    },
    //清除脏数据
    _clearDirty : function(type,saveData){
      var _self = this;
      switch(type){
        case  &#39;all&#39; : 
          _self._clearChanges();
          break;
        case &#39;add&#39; : 
          removeFrom(saveData,&#39;newRecords&#39;);
          break;
        case &#39;update&#39; : 
          removeFrom(saveData,&#39;modifiedRecords&#39;);
          break;
        case &#39;remove&#39; : 
          removeFrom(saveData,&#39;deletedRecords&#39;);
          break;
        default : 
          break;
      }
      function removeFrom(obj,name){
        BUI.Array.remove(_self.get(name),obj);
      }
    },
<span id='BUI-Data-Store-method-sort'>    /**
</span>     * 排序，如果remoteSort = true,发送请求，后端排序
     * &lt;pre&gt;&lt;code&gt;
     *   store.sort(&#39;id&#39;,&#39;DESC&#39;); //以id为排序字段，倒序排序
     * &lt;/code&gt;&lt;/pre&gt;
     * @param  {String} field     排序字段
     * @param  {String} direction 排序方向
     */
    sort : function(field,direction){
      var _self = this,
        remoteSort = _self.get(&#39;remoteSort&#39;);

      if(!remoteSort){
        _self._localSort(field,direction);
      }else{
        _self.set(&#39;sortField&#39;,field);
        _self.set(&#39;sortDirection&#39;,direction);
        _self.load(_self.get(&#39;sortInfo&#39;));
      }
    },
<span id='BUI-Data-Store-method-sum'>    /**
</span>     * 计算指定字段的和
     * &lt;pre&gt;&lt;code&gt;
     *   var sum = store.sum(&#39;number&#39;);
     * &lt;/code&gt;&lt;/pre&gt;
     * @param  {String} field 字段名
     * @param  {Array} [data] 计算的集合，默认为Store中的数据集合
     * @return {Number} 汇总和
     */
    sum : function(field,data){
      var  _self = this,
        records = data || _self.getResult(),
        sum = 0;
      BUI.each(records,function(record){
        var val = record[field];
        if(!isNaN(val)){
          sum += parseFloat(val);
        }
      });
      return sum;
    },
<span id='BUI-Data-Store-method-setValue'>    /**
</span>    * 设置记录的值 ，触发 update 事件
    * &lt;pre&gt;&lt;code&gt;
    *  store.setValue(obj,&#39;value&#39;,&#39;new value&#39;);
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Object} obj 修改的记录
    * @param {String} field 修改的字段名
    * @param {Object} value 修改的值
    */
    setValue : function(obj,field,value){
      var record = obj,
        _self = this;

      record[field]=value;
      if(!contains(record,_self.get(&#39;newRecords&#39;)) &amp;&amp; !contains(record,_self.get(&#39;modifiedRecords&#39;))){
          _self.get(&#39;modifiedRecords&#39;).push(record);
      }
      _self.fire(&#39;update&#39;,{record:record,field:field,value:value});
    },
<span id='BUI-Data-Store-method-update'>    /**
</span>    * 更新记录 ，触发 update事件
    * &lt;pre&gt;&lt;code&gt;
    *   var record = store.find(&#39;id&#39;,&#39;12&#39;);
    *   record.value = &#39;new value&#39;;
    *   record.text = &#39;new text&#39;;
    *   store.update(record); //触发update事件，引起绑定了store的控件更新
    * &lt;/code&gt;&lt;/pre&gt;
    * @param {Object} obj 修改的记录
    * @param {Boolean} [isMatch = false] 是否需要进行匹配，检测指定的记录是否在集合中
    * @param {Function} [match = matchFunction] 匹配函数
    */
    update : function(obj,isMatch,match){
      var record = obj,
        _self = this,
        match = null,
        index = null;
      if(isMatch){
        match = match || _self._getDefaultMatch();
        index = _self.findIndexBy(obj,match);
        if(index &gt;=0){
          record = _self.getResult()[index];
        }
      }
      record = BUI.mix(record,obj);
      if(!contains(record,_self.get(&#39;newRecords&#39;)) &amp;&amp; !contains(record,_self.get(&#39;modifiedRecords&#39;))){
          _self.get(&#39;modifiedRecords&#39;).push(record);
      }
      _self.fire(&#39;update&#39;,{record:record});
    },
    //添加纪录
    _addRecord :function(record,index){
      var records = this.getResult();
      if(index == undefined){
        index = records.length;
      }
      records.splice(index,0,record);
      this.fire(&#39;add&#39;,{record:record,index:index});
    },
    //清除改变的数据记录
    _clearChanges : function(){
      var _self = this;
      BUI.Array.empty(_self.get(&#39;newRecords&#39;));
      BUI.Array.empty(_self.get(&#39;modifiedRecords&#39;));
      BUI.Array.empty(_self.get(&#39;deletedRecords&#39;));
    },
<span id='BUI-Data-Store-method-_filterLocal'>    /**
</span>     * @protected
     * 过滤缓存的数据
     * @param  {Function} fn 过滤函数
     * @return {Array} 过滤结果
     */
    _filterLocal : function(fn,data){

      var _self = this,
        rst = [];
      data = data || _self.getResult();
      if(!fn){ //没有过滤器时直接返回
        return data;
      }
      BUI.each(data,function(record){
        if(fn(record)){
          rst.push(record);
        }
      });
      return rst;
    },
    //获取默认的匹配函数
    _getDefaultMatch :function(){

      return this.get(&#39;matchFunction&#39;);
    },

    //获取分页相关的信息
    _getPageParams : function(){
      var _self = this,
        sortInfo = _self.get(&#39;sortInfo&#39;),
        start = _self.get(&#39;start&#39;),
        limit = _self.get(&#39;pageSize&#39;),
        pageIndex = _self.get(&#39;pageIndex&#39;) || (limit ? start/limit : 0);

        params = {
          start : start,
          limit : limit,
          pageIndex : pageIndex //一般而言，pageIndex = start/limit
        };

      if(_self.get(&#39;remoteSort&#39;)){
        BUI.mix(params,sortInfo);
      }

      return params;
    },
<span id='BUI-Data-Store-method-getAppendParams'>     /**
</span>     * 获取附加的参数,分页信息，排序信息
     * @override
     * @protected
     * @return {Object} 附加的参数
     */
    getAppendParams : function(){
      return this._getPageParams();
    },
<span id='BUI-Data-Store-method-beforeInit'>    /**
</span>     * @protected
     * 初始化之前
     */
    beforeInit : function(){
      //初始化结果集
      this._setResult([]);
    },
    //本地排序
    _localSort : function(field,direction){
      var _self = this;

      _self._sortData(field,direction);

      _self.fire(&#39;localsort&#39;,{field:field,direction:direction});
    },
    _sortData : function(field,direction,data){
      var _self = this;
      data = data || _self.getResult();

      _self.sortData(field,direction,data);
    },
    //处理数据
    afterProcessLoad : function(data,params){
      var _self = this,
        root = _self.get(&#39;root&#39;),
        start = params.start,
        limit = params.limit,
        totalProperty = _self.get(&#39;totalProperty&#39;);

      if(BUI.isArray(data)){
        _self._setResult(data);
      }else{
        _self._setResult(BUI.getValue(data,root), BUI.getValue(data,totalProperty));
      }

      _self.set(&#39;start&#39;,start);

      if(limit){
        _self.set(&#39;pageIndex&#39;,start/limit);
      }

      //如果本地排序,则排序
      if(!_self.get(&#39;remoteSort&#39;)){
        _self._sortData();
      }

      _self.fire(&#39;load&#39;,{ params : params });

      //如果有本地过滤，则本地过滤
      if(!_self.get(&#39;remoteFilter&#39;) &amp;&amp; _self.get(&#39;filter&#39;)){
        _self.filter(_self.get(&#39;filter&#39;));
      }
    },
    //设置结果集
    _setResult : function(rows,totalCount){
      var _self = this,
        resultMap = _self.get(&#39;resultMap&#39;);

      totalCount = totalCount || rows.length;

      BUI.setValue(resultMap,_self.get(&#39;root&#39;),rows);
      BUI.setValue(resultMap,_self.get(&#39;totalProperty&#39;),totalCount);

      //清理之前发生的改变
      _self._clearChanges();
    }
  });

module.exports = store;
</pre>
</body>
</html>
